/*
 *  Cero Project - Copyright   2006 The Cero Developement Team 
 *  (Michael Laguerre, Camille Roux, Matthieu Segret, Mathieu Sivade) 
 * 
 *  This program is free software; you can redistribute it and/or modify it 
 *  under the terms of the GNU General Public License as published by the Free 
 *  Software Foundation; either version 2 of the License, or (at your option) 
 *  any later version.
 * 
 *  This program is distributed in the hope that it will be useful, but 
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 *  for more details.
 */

package org.ceroproject.games;

import java.util.Collection;
import java.util.List;

import org.ceroproject.SortableCollection;
import org.ceroproject.SortableList;


/**
 * Represents a game.
 * 
 * @author Telem
 */
public interface Game {

	/**
	 * Returns the collection of actions any player can do
	 * 
	 * @return the collection of actions any player can do
	 * @see Action
	 */
	Collection<Action> getActions();

	/**
	 * Returns a sortable (for priority matters) collection of the ActionRules
	 * used during the game.
	 * 
	 * @return the ActionRules used during the game
	 * @see ActionRule
	 */
	SortableCollection<ActionRule> getActionRules();

	/**
	 * Returns a collection of the Rules used during the game.
	 * 
	 * @return the Rules used during the game
	 * @see Rule
	 */
	Collection<Rule> getRules();

	/**
	 * Returns a sortable (for priority matters) collection of the
	 * GameInitializers used in the game.
	 * 
	 * @return the GameInitializers used in the game
	 * @see GameInitializer
	 */
	SortableCollection<GameInitializer> getGameInitializers();

	/**
	 * Returns a sortable (for priority matters) collection of the
	 * StopConditions used to stop the game.
	 * 
	 * @return the StopConditions used in the game
	 * @see StopCondition
	 */
	SortableCollection<StopCondition> getGameStopConditions();

	/**
	 * The zones shared by all the players
	 * 
	 * @return The zones shared by all the players
	 * @see Zone
	 */
	ZonesGroup getZones();

	/**
	 * Returns the list of rounds played in a game
	 * 
	 * @return the list of rounds played in a game
	 */
	List<Round> getRounds();

	/**
	 * Returns a sortable list of the players. This allows to modify the
	 * player's seat order during the game.
	 * 
	 * @return a SortableList of the players
	 */
	SortableList<Player> getPlayers();

	/**
	 * Starts the game. First checks if the rules allow the game to be launched,
	 * then initializes the game. Once this is done, it loops through the rounds
	 * again and again until a StopCondition is fulfilled.
	 * 
	 * @throws InitializationException
	 *             If the initialization screwed
	 * @throws ValidationException
	 *             If one of the rules doesn't validate the game
	 */
	void startGame() throws InitializationException, ValidationException;

	/**
	 * Stops the game as soon as possible.
	 */
	void stopGame();

	/**
	 * Adds a game listener to this game
	 * 
	 * @param listener
	 *            the listener to add
	 * @return whether the listener has been added or not
	 */
	boolean addGameListener(GameListener listener);

	/**
	 * Removes a game listener from this game
	 * 
	 * @param listener
	 *            the listener to remove
	 * @return whether the listener has been removed or not
	 */
	boolean removeGameListener(GameListener listener);

	/**
	 * Adds an action listener to this game
	 * 
	 * @param listener
	 *            the listener to add
	 * @return whether the listener has been added or not
	 */
	boolean addActionListener(ActionListener listener);

	/**
	 * Removes an action listener from this game
	 * 
	 * @param listener
	 *            the listener to remove
	 * @return whether the listener has been removed or not
	 */
	boolean removeActionListener(ActionListener listener);

	/**
	 * Checks if the rules validate the current state of the game. If they
	 * don't, a ValidationException will be thrown.
	 * 
	 * @throws ValidationException
	 *             if a rule doesn't validate the game as it is.
	 */
	void validate() throws ValidationException;

	/**
	 * Registers the Action 'action' so that it gets executed as soon as
	 * possible
	 * 
	 * @param action
	 *            the action to register
	 * @throws ActionException
	 *             if the game is not currently playing
	 */
	void registerAction(Action action);

	/**
	 * Returns the name of the game
	 * 
	 * @return the name of the game
	 */
	String getGameName();
}
